<!DOCTYPE html>
<html lang="pt-br">
	<head>
		<meta charset="utf-8">
		<base href="../../../" />
		<script src="page.js"></script>
		<link type="text/css" rel="stylesheet" href="page.css" />
	</head>
	<body>
		<h1>Testando com NPM</h1>

		<p class="desc">
            Este artigo mostra como colocar o three.js em um ambiente [link:https://nodejs.org/en/ node.js] para que você
            possa executar testes automatizados. Os testes podem ser executados na linha de comando ou por
            ferramentas de CI como [link:https://travis-ci.org/ Travis].
		</p>

		<h2>A versão curta</h2>

		<p>
			Se você estiver confortável com node e npm,
			<code>
				$ npm install three --save-dev
			</code>
			e adicione
		<code>
			const THREE = require('three');
		</code>
			para o seu teste.
		</p>

		<h2>Criar um projeto testável do zero</h2>
		<p>
            Se você não estiver familiarizado com essas ferramentas, aqui está um guia rápido (para linux, o processo de instalação
            será um pouco diferente do que usando o Windows, mas os comandos do NPM são idênticos).
		</p>

		<h3>Configuração básica</h3>
		<div>
			<ol>
				<li>
					Instale o [link:https://www.npmjs.org/ npm] e o nodejs. O caminho mais curto normalmente parece algo como
					<code>
$ sudo apt-get install -y npm nodejs-legacy
# fix any problems with SSL in the default registry URL
$ npm config set registry http://registry.npmjs.org/
					</code>
				</li>

				<li>
					Crie um novo diretório de projeto
					<code>
						 $ mkdir test-example; cd test-example
					</code>
				</li>

				<li>
					Peça ao npm para criar um novo arquivo de projeto para você:
					<code>
					 $ npm init
					</code>
                    e aceite todas as opções default pressionando Enter em todos os prompts.
                    Isso criará o package.json.
				</li><br />

				<li>
					Experimente iniciar o recurso de teste com
					<code>
$ npm test
					</code>
					Isso falhará, o que é esperado.
                    Se você olhar no package.json, a definição do script de teste é
					<code>
						"test": "echo \"Error: no test specified\" && exit 1"
					</code>
				</li>

			</ol>
		</div>

		<h2>Adicionar mocha</h2>
		<div>
			Vamos usar o [link:https://mochajs.org/mocha].

			<ol>
				<li>
					Instale o mocha com
					<code>
$ npm install mocha --save-dev
					</code>
					Observe que a pasta node_modules/ é criada e suas dependências aparecem lá.
                    Observe também que seu package.json foi atualizado: a propriedade devDependencies
                    é adicionada e atualizada pelo uso de --save-dev.
				</li><br />

				<li>
                    Edite o package.json para usar o mocha para teste. Quando o teste for chamado, queremos apenas executar
                    o mocha e especificar um relatório detalhado. Por padrão, isso executará qualquer coisa em test/
                    (não ter a pasta test/ pode levar a um ERR! no npm, crie-a pelo comando mkdir test)
					<code>
						"test": "mocha --reporter list"
					</code>
				</li>

				<li>
					Reexecute o teste com
					<code>
						$ npm test
					</code>
                    Isso agora deve correr bem, reportando "0 passing (1ms)"
                    ou similar.
				</li>

			</ol>
		</div>

		<h2>Adicionar three.js</h2>
		<div>
			<ol>
				<li>
					Vamos baixar nossa dependência three.js com
					<code>
$ npm install three --save-dev
					</code>
					<ul>
						<li>
							Se você precisar de uma versão diferente do three.js, use
							<code>
								$ npm show three versions
							</code>
                          para listar o que está disponível. Para escolher pelo npm a versão correta, use
							<code>
 $ npm install three@0.84.0 --save
							</code>
							(0.84.0 nesse exemplo). --save torna isso uma dependência do projeto, em vez de
                            dependência dev. Veja os documentos [link:https://docs.npmjs.com/cli/v8/configuring-npm/package-json aqui] para mais informações.
						</li>
					</ul>
				</li>

				<li>
					Mocha irá procurar por testes em test/, então vamos executar
					<code>
					$ mkdir test
					</code>
				</li>

				<li>
                    Finalmente, precisamos de um teste JS para ser executado. Vamos adicionar um teste simples que verificará que
                    o objeto three.js está disponível e funcionando. Crie test/verify-three.js contendo:
<code>
const THREE = require('three');
const assert = require('assert');

describe('The THREE object', function() {
  it('should have a defined BasicShadowMap constant', function() {
    assert.notEqual('undefined', THREE.BasicShadowMap);
  }),

  it('should be able to construct a Vector3 with default of x=0', function() {
    const vec3 = new THREE.Vector3();
    assert.equal(0, vec3.x);
  })
})
</code>
				</li>

				<li>
                Finalmente vamos testar novamente com $ npm test. Isso deve executar os testes acima e ter sucesso,
                mostrando algo como:
				<code>
The THREE object should have a defined BasicShadowMap constant: 0ms
The THREE object should be able to construct a Vector3 with default of x=0: 0ms
2 passing (8ms)
				</code>
				</li>
			</ol>
		</div>

		<h2>Adicione seu próprio código</h2>
		<div>
			Você precisa fazer três coisas:

			<ol>
				<li>
					Escreva um teste para o comportamento esperado do seu código e coloque-o em test/.
					[link:https://github.com/air/encounter/blob/master/test/Physics-test.js aqui] tem um exemplo de um projeto real.
				</li>

				<li>
					Exporte seu código funcional de forma que o nodejs possa vê-lo, para uso em conjunto com require.
					Veja isso [link:https://github.com/air/encounter/blob/master/js/Physics.js aqui].
				</li>

				<li>
                    Requisite seu código no arquivo de teste, da mesma forma que fizemos um require('three') no exemplo acima.
				</li>
			</ol>

			<p>
                Os itens 2 e 3 variam dependendo de como você gerencia seu código. No exemplo de Physics.js
                dado acima, a parte de exportação está bem no final. Atribuímos um objeto a module.exports:
			</p>
			<code>
//=============================================================================
// make available in nodejs
//=============================================================================
if (typeof exports !== 'undefined')
{
  module.exports = Physics;
}
			</code>
		</div>

		<h2>Lidando com dependências</h2>
		<div>
			<p>
				Se você já estiver usando algo como require.js ou browserify, pule esta parte.
			</p>
			<p>
                Normalmente, um projeto three.js será executado no navegador. O carregamento do módulo é, portanto, feito pelo 
                navegador, executando um monte de tags de script. Seus arquivos individuais não precisam se preocupar
                com dependências. No entanto, em um contexto nodejs, não há index.html vinculando tudo
                junto, então você tem que ser explícito.
			</p>
			<p>
				Se você estiver exportando um módulo que depende de outros arquivos, precisará dizer ao node para carregá-los.
                Aqui está uma abordagem:
			</p>
			<ol>
				<li>
					No início do seu módulo, verifique se você está em um ambiente nodejs.
				</li>
				<li>
					Em caso afirmativo, declare explicitamente suas dependências.
				</li>
				<li>
					Caso contrário, você provavelmente está em um navegador, então não precisa fazer mais nada.
				</li>
			</ol>
			Código de exemplo de Physics.js:
			<code>
//=============================================================================
// setup for server-side testing
//=============================================================================
if (typeof require === 'function') // test for nodejs environment
{
  const THREE = require('three');
  const MY3 = require('./MY3.js');
}
			</code>
		</div>

	</body>
</html>
